﻿

//using System;
//using System.Diagnostics;
//using System.IO;
//using System.Runtime.InteropServices;
//using System.Security.Principal;
//namespace WatchDog.Core
//{
//    // 辅助方法，获取当前Windows登录用户角色身份
//    public static class UserRoleCheckUtils
//    {
//        public static bool? OsCurrentUserIsAdministrator(out Exception ex)
//        {
//            bool? isAdministrator = null;
//            ex = null;
//            try
//            {
//                var windowsIdentity = WindowsIdentity.GetCurrent();
//                var windowsPrincipal = new WindowsPrincipal(windowsIdentity);

//                isAdministrator = windowsPrincipal.IsInRole(WindowsBuiltInRole.Administrator);
//            }
//            catch (Exception exception)
//            {
//                ex = exception;
//            }
//            return isAdministrator;
//        }
//    }


//    public class ShellUtils
//    {
//        #region ShellExecute
//        public enum ShowCommands : int
//        {
//            SW_HIDE = 0,
//            SW_SHOWNORMAL = 1,
//            SW_NORMAL = 1,
//            SW_SHOWMINIMIZED = 2,
//            SW_SHOWMAXIMIZED = 3,
//            SW_MAXIMIZE = 3,
//            SW_SHOWNOACTIVATE = 4,
//            SW_SHOW = 5,
//            SW_MINIMIZE = 6,
//            SW_SHOWMINNOACTIVE = 7,
//            SW_SHOWNA = 8,
//            SW_RESTORE = 9,
//            SW_SHOWDEFAULT = 10,
//            SW_FORCEMINIMIZE = 11,
//            SW_MAX = 11
//        }
//        [DllImport("shell32.dll", CharSet = CharSet.Auto, SetLastError = true)]
//        static extern IntPtr ShellExecute(
//            IntPtr hwnd,
//            string lpOperation,
//            string lpFile,
//            string lpParameters,
//            string lpDirectory,
//            ShowCommands nShowCmd);

//        #endregion

//        #region ShellExecuteEx
//        private const int SwShow = 5;
//        private const uint SeeMaskInvokeidlist = 12;

//        /// <summary>
//        /// 对指定应用程序执行某个操作
//        /// </summary>
//        /// <param name="lpExecInfo"></param>
//        /// <returns></returns>
//        [DllImport("shell32.dll", CharSet = CharSet.Auto, SetLastError = true)]
//        public static extern bool ShellExecuteEx(ref Shellexecuteinfo lpExecInfo);
//        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
//        public struct Shellexecuteinfo
//        {
//            /// <summary>
//            /// 结构大小，以字节为单位
//            /// </summary>
//            public int cbSize;
//            /// <summary>
//            /// 一个标志数组，用来设置其他成员的有效性。
//            /// </summary>
//            public uint fMask;
//            /// <summary>
//            /// 可选。执行ShellExecuteEx的窗口句柄，可设为NULL。
//            /// </summary>
//            public IntPtr hwnd;
//            /// <summary>
//            /// 指定执行的动作，包括：edit ，explore ，find ，open，print， properties
//            /// </summary>
//            [MarshalAs(UnmanagedType.LPTStr)]
//            public string lpVerb;
//            /// <summary>
//            /// 以\0 结尾的字符串，指出 lpVerb 的操作对象的路径，被系统支持的操作包括文本的 open 、 print等
//            /// </summary>
//            [MarshalAs(UnmanagedType.LPTStr)]
//            public string lpFile;
//            /// <summary>
//            /// 可选。运行/打开程序的参数，如果打开的是一个文档，则该项无效
//            /// </summary>
//            [MarshalAs(UnmanagedType.LPTStr)]
//            public string lpParameters;
//            /// <summary>
//            /// 可选。指明工作目录的名字，成员没有说明，则默认为当前目录
//            /// </summary>
//            [MarshalAs(UnmanagedType.LPTStr)]
//            public string lpDirectory;
//            /// <summary>
//            /// 必须。指定打开的程序的显示方式，为SW_值中的一个。
//            /// </summary>
//            public int nShow;
//            /// <summary>
//            /// 【out】如果设置SEE_MASK_NOCLOSEPROCESS S值并且ShellExecuteEx 调用成功，则该项的值大于32，如果调用失败，则将设置为 SE_ERR_XXX 的错误值。
//            /// </summary>
//            public IntPtr hInstApp;
//            /// <summary>
//            /// 一个ITEMIDLIST结构的地址，用来存储成员的特别标识符，当fMask不包括SEE_MASK_IDLIST或SEE_MASK_INVOKEIDLIST时该项被忽略
//            /// </summary>
//            public IntPtr lpIDList;
//            /// <summary>
//            /// 用以指明文件类别的名字或GUID，当fMask不包括SEE_MASK_CLASSNAME时该项被忽略
//            /// </summary>
//            [MarshalAs(UnmanagedType.LPTStr)]
//            public string lpClass;
//            /// <summary>
//            /// 获得已在系统注册的文件类型的Handle，当fMask不包括SEE_MASK_HOTKEY时该项被忽略
//            /// </summary>
//            public IntPtr hkeyClass;
//            /// <summary>
//            /// 程序的热键关联，低位存储虚拟关键码（Key Code），高位存储修改标志位(HOTKEYF_)，修改标志为（modifier flags）的详细列表请看WM_SETHOTKEY消息的描述，当fmask不包括SEE_MASK_HOTKEY时该项被忽略
//            /// </summary>
//            public uint dwHotKey;
//            /// <summary>
//            /// 取得对应文件类型的图标的Handle，当fMask不包括SEE_MASK_ICON时该项被忽略
//            /// </summary>
//            public IntPtr hIcon;
//            /// <summary>
//            /// 指向新启动的程序的句柄。若fMask不设为SEE_MASK_NOCLOSEPROCESS则该项值为NULL。但若程序没有启动，即使fMask设为SEE_MASK_NOCLOSEPROCESS，该值也仍为NULL。
//            /// </summary>
//            public IntPtr hProcess;
//        }

//        public static bool Execute(string verb, string fileFullPath, string arguments)
//        {
//            ShellUtils.Shellexecuteinfo info = new ShellUtils.Shellexecuteinfo();
//            info.cbSize = Marshal.SizeOf(info);
//            info.fMask = SeeMaskInvokeidlist;
//            info.lpVerb = verb;
//            info.lpFile = fileFullPath;
//            info.lpParameters = arguments;
//            info.nShow = SwShow;

//            return ShellExecuteEx(ref info);
//        }

//        #endregion
//    }

//    // AddinHelper，主要是提供操作系统登录用户角色判断、Process方法调用和ShellUtils.Execute方法的调用
//    public class AddinHelper
//    {

//        public static bool RegisterAddIn(string dllPath, bool isBit64)
//        {
//            string winDir = Environment.GetFolderPath(Environment.SpecialFolder.Windows);
//            string regasmPath;
//            if (isBit64)
//            {
//                regasmPath = Path.Combine(winDir, @"Microsoft.NET\Framework64\v4.0.30319\RegAsm.exe");
//            }
//            else
//            {
//                regasmPath = Path.Combine(winDir, @"Microsoft.NET\Framework\v4.0.30319\RegAsm.exe");
//            }
//            //获取当前操作系统登录用户角色是否是超级管理员
//            var osCurrentUserIsAdministrator = UserRoleCheckUtils.OsCurrentUserIsAdministrator(out Exception ex);
//            //如果是超管、使用process方式注册；否则使用ShellExecuteEx方式
//            if (osCurrentUserIsAdministrator.HasValue && osCurrentUserIsAdministrator.Value)
//            {
//                return UseProcessOperateAddIn(regasmPath, " /codebase \"" + dllPath + "\"");
//            }
//            //如果获取用户身份失败或者是普通用户，将提权注册插件
//            return ShellUtils.Execute("runas", regasmPath, dllPath);
//        }

//        /// <summary>
//        /// 操作COM插件
//        /// </summary>
//        /// <param name="regasmPath"></param>
//        /// <param name="dllPath">含其他操作命令</param>
//        /// <returns></returns>
//        public static bool UseProcessOperateAddIn(string regasmPath, string dllPath)
//        {
//            try
//            {
//                var startInfo = new ProcessStartInfo();
//                startInfo.Verb = string.Empty;
//                startInfo.FileName = regasmPath;
//                startInfo.Arguments = dllPath;
//                startInfo.WindowStyle = ProcessWindowStyle.Normal;
//                startInfo.RedirectStandardOutput = true;
//                startInfo.RedirectStandardError = true;
//                startInfo.RedirectStandardInput = true;
//                startInfo.UseShellExecute = false;
//                startInfo.CreateNoWindow = true; //让窗体不显示
//                startInfo.ErrorDialog = false;
//                Process process = Process.Start(startInfo);
//                process.EnableRaisingEvents = true;
//                process.WaitForExit();
//                StreamReader reader = process.StandardOutput; //截取输出流
//                string output = process.StandardError.ReadToEnd();
//                var rtn = process.ExitCode;
//                if (rtn != 0)
//                    throw new Exception(output);
//                return true;
//            }
//            catch (Exception ex)
//            {
//                return false;
//            }
//        }

//    }
//}

